#!/usr/bin/env python

import struct
import sys
import FATDE

class FATLFN:
   FATLFNFormat = "<B10sBBB12sH4s"
   def size(self):
      return struct.calcsize(self.FATLFNFormat)

   # See http://en.wikipedia.org/wiki/File_Allocation_Table#Long_file_names_2
   def longFileName(self):
      longFileName = (self.attr == 0x0f) and (self.reserved == 0) and (self.cluster == 0)

      return longFileName

   def isLongFileName(self):
      return self.longFileName()

   def __init__(self, buffer):
      self.parse(buffer)

   def parse(self, buffer):
      item = struct.unpack(self.FATLFNFormat, buffer)

      self.sequence = item[0]
      self.rawname = item[1] + item[5] + item[7]
      # terminated by two zeros
      for i in range(0, len(self.rawname), 2):
         if ord(self.rawname[i]) == 0 and ord(self.rawname[i+1]) == 0:
            self.rawname = self.rawname[0:i]
            break
         
      self.attr = item[2]
      self.reserved = item[3]
      self.chksum = item[4]
      self.cluster = item[6]
      
   def deleted(self):
      return self.sequence == 0xe5

   def getName(self):
      try:
         name = unicode(self.rawname, 'utf-16').encode('utf-8')
      except UnicodeDecodeError:
         name = "Unicode error " + self.getHexName()
         
      return name
         
   def getHexName(self):
      return str([hex(ord(x)) for x in self.rawname])
      
   def sequenceNumber(self):
      return self.sequence & ~ 0x40

   def endSequence(self):
      return self.sequence & 0x40 == 0x40

   def __str__(self) :
      string = 'LFN: '
      string += hex(self.sequence)
      string += ", " + hex(self.attr)
      string += ", " + hex(self.cluster)
      string += ", " + hex(self.chksum)
      string += ", " + self.getName()

      return string

if __name__ == '__main__':
   # Read in some entries from stdin
   for i in range(10):
      buffer = sys.stdin.read(0x20)
      fatde = FATDE.FATDE(buffer);
      print fatde.toString()
      print

